/********************************************************************
	Coder: vincent
	E-Mail:	vincent213@live.cn
*********************************************************************/

using UnityEngine;
using System.Collections;
using System.Collections.Generic;



public abstract class Action  {
	

	
	public Action()
	{
		m_fPassTime = 0.0f;
		m_State = ActionState.Stop;
		m_fPauseTime = 0;
		m_fPauseStartTime = 0;
		m_vVel = new Vector3(0,0,0);
	}
	
	public Action(GameObject obj)
	{
		m_fPassTime = 0.0f;
		m_State = ActionState.Stop;
		m_fPauseTime = 0;
		m_fPauseStartTime = 0;
		m_vVel = new Vector3(0,0,0);
		m_GameOBJ = obj;
	}
	
	//local update function,other clinet not run,use for physics,state control
	abstract public bool Condition();
	abstract public void Enter();
	abstract public void Update();
	abstract public void End();
	
	//local and remote client update function,use for visual 
	abstract public void EnterVisual();
	abstract public void UpdateVisual();
	abstract public void EndVisual();
	
	virtual public void ExectureEnter(bool bLocal)
	{
		if(bLocal)
			Enter();
		EnterVisual();
	}
	
	virtual public void ExectureUpdate(bool bLocal)
	{
		if(bLocal)
			Update();
		UpdateVisual();
	}
	
	virtual public void ExectureEnd(bool bLocal)
	{
		if(bLocal)
			End();
		EndVisual();
	}
	
	virtual public void ApplyAnim(string strAnim)
	{
		if(m_GameOBJ != null)
		{
            m_AnimControl.SetWrapMode(strAnim,m_ActionData.m_AnimWrapMode);
            m_AnimControl.SetSpeed(strAnim,GetAnimSpeed());
            if (m_ActionData.m_bFadeAnim)
                m_AnimControl.CrossFade(strAnim);
            else
                m_AnimControl.Play(strAnim);
			//m_GameOBJ.animation[strAnim].wrapMode = m_ActionData.m_AnimWrapMode;
			//m_GameOBJ.animation[strAnim].speed = GetAnimSpeed();
			//m_GameOBJ.animation[strAnim].layer = (int)m_ActionData.m_AnimLayer;
			//if(m_ActionData.m_bFadeAnim)
			//	m_GameOBJ.animation.CrossFade(strAnim);
			//else
			//	m_GameOBJ.animation.Play(strAnim);
		}
	}
	
	
	virtual public void Start(bool bLocal)
	{
		Reset();
//        if (m_ActionData.m_bTurnToAttackTarget)
//        {
//            Vector3 vec = PlayerManager.instance.GetNearAttackObjVec(m_GameOBJ);
//            vec.y = 0;
//            if (vec != Vector3.zero && vec.sqrMagnitude < 20.0f)
//                m_TargetRotate = Quaternion.LookRotation(vec);
//
//        }
        if(m_ActionData.m_bUseAnimTime)
			m_ActionData.m_fDuration = m_AnimControl.GetLength(m_ActionData.m_strAnimName)*m_ActionData.m_AnimSpeed;
		m_State = ActionState.Play;
        ApplyAnim(m_ActionData.m_strAnimName);
		
//		PlayerData data = (PlayerData)m_GameOBJ.GetComponent("PlayerData");
		ExectureEnter(bLocal);
		
       
		
	}
	
	virtual public void Reset()
	{
        m_fPassTime = 0.0f;
        m_TargetRotate = m_GameOBJ.transform.rotation;
        m_vLastApplyForce = Vector3.zero;

        for(int i=0; i<m_listEffectDataProcess.Count; i++)
		{
			m_listEffectDataProcess[i].Reset();
		}
		
		for(int i=0; i<m_listHitDataProcess.Count; i++)
		{
			m_listHitDataProcess[i].Reset();
		}
		
		 for(int i=0; i<m_listForceDataProcess.Count; i++)
		{
			m_listForceDataProcess[i].Reset();
		}
		
	}
	
	public Transform GetTransform()
	{
		return m_GameOBJ.transform;
	}
	
	public Animation GetAnimation()
	{
		return m_GameOBJ.animation;
	}
	
	public void Pause(float fPauseTime)
	{
		m_State = ActionState.Pause;
		m_fPauseStartTime = Time.time;
		m_fPauseTime = fPauseTime;
		//m_GameOBJ.animation[m_ActionData.m_strAnimName].speed = 0.05f;
        m_AnimControl.SetSpeed(m_ActionData.m_strAnimName,0.05f);
		m_GameOBJ.rigidbody.Sleep();

	}
	
	public void Play()
	{
		m_State = ActionState.Play;

        m_AnimControl.SetSpeed(m_ActionData.m_strAnimName, GetAnimSpeed());
        if (m_GameOBJ.rigidbody.IsSleeping())
        {
            m_GameOBJ.rigidbody.WakeUp();
            if (m_vLastApplyForce != Vector3.zero)
            {
                ApplyForce(m_vLastApplyForce * 0.5f);
                m_vLastApplyForce = Vector3.zero;
            }
        }  
	}
	
	public bool IsInAir()
	{
		return m_ActionData.m_PhysicsType == ActionPhysicsType.Air;
	}
	
	public void SetDuration(float fDuration)
	{
		m_ActionData.m_fDuration = fDuration;
	}
	
	public float GetDuration()
	{
		return m_ActionData.m_fDuration/m_ActionData.m_fActionSpeed;
	}
	
	public string GetName()
	{
		return m_ActionData.m_strName;
	}

    public void SetState(ActionState state)
    {
        m_State = state;
    }

	public ActionState GetState()
	{
		return m_State;
	}
	
	public ActionPlayMode GetPlayMode()
	{
		return m_ActionData.m_ActPlayMode;
	}
	
	public float GetActionSpeed()
	{
		return m_ActionData.m_fActionSpeed;
	}
	
	public void SetActionSpeed(float fSpeed)
	{
		m_ActionData.m_fActionSpeed = fSpeed;
	}
	
	public int GetPriority()
	{
		return m_ActionData.m_nPriority;
	}
	
	public float GetPassTime()
	{
		return m_fPassTime;
	}
	
	public void SetPassTime(float fTime)
	{
		m_fPassTime = fTime;
	}
	
	public Vector3 GetVel()
	{
		return m_vVel;
	}
	
	public float GetPauseStartTime()
	{
		return m_fPauseStartTime;
	}
	
	public float GetPauseTime()
	{
		return m_fPauseTime;
	}
	
	public string GetEndToAction()
	{
		return m_ActionData.m_strEndToAction;
	}
	
	public int GetActionID()
	{
		return m_ActionData.m_nActionID;
	}
	
	public float GetAnimSpeed()
	{
		return m_ActionData.m_AnimSpeed*m_ActionData.m_fActionSpeed;
	}
	
	public float GetOriAnimSpeed()
	{
		return m_ActionData.m_AnimSpeed;
	}
	
	public Quaternion GetTargetRotate()
	{
		return m_TargetRotate;
	}
	
	public string GetAnimName()
	{
		return m_ActionData.m_strAnimName;
	}
	
	public float GetAnimTime()
	{
		return m_AnimControl.GetTime(m_ActionData.m_strAnimName);
	}
	
	public float GetAnimLength()
	{
		return m_AnimControl.GetLength(m_ActionData.m_strAnimName);
	}
	
	public void InitDataProcess()
	{
		InitHitDataProcess();
		InitEffectDataProcess();
		InitForceDataPorcess();
	}
	
	public void InitEffectDataProcess()
	{
		if(m_ActionData.vecEffectData == null)
			return ;
		
		for(int i=0; i<m_ActionData.vecEffectData.Count; i++)
		{
			m_listEffectDataProcess.Add(new EffectDataProcess());
		}
	}
	
	public void InitHitDataProcess()
	{
		if(m_ActionData.vecHitData == null)
			return ;
			
		for(int i=0; i<m_ActionData.vecHitData.Count; i++)
		{
			m_listHitDataProcess.Add(new HitDataProcess());	
		}
	}
	
	public void InitForceDataPorcess()
	{
		if(m_ActionData.vecForceData == null)
			return ;
		for(int i=0; i<m_ActionData.vecForceData.Count; i++)
		{
			m_listForceDataProcess.Add(new EffectDataProcess());
		}
	}

    public void ApplyForce(Vector3 vForce)
    {
        m_GameOBJ.rigidbody.AddForce(m_GameOBJ.transform.forward*vForce.x+m_GameOBJ.transform.right*vForce.z+m_GameOBJ.transform.up*vForce.y);
        m_vLastApplyForce = vForce;
    }
	
	public AnimControl GetAnimControl()
	{
		return m_AnimControl;
	}
	
	public ActionStaticData m_ActionData;
	
	public ActionState   m_State{set;get;}
	public float  m_fPassTime{set;get;}
	public float  m_fPauseStartTime{set;get;}
	public float  m_fPauseTime{set;get;}
	public Vector3  m_vVel;
	public List<HitDataProcess> m_listHitDataProcess = new List<HitDataProcess>();
	public List<EffectDataProcess> m_listEffectDataProcess = new List<EffectDataProcess>();
	public List<EffectDataProcess> m_listForceDataProcess = new List<EffectDataProcess>();
	
	public GameObject m_GameOBJ;
	public Quaternion m_TargetRotate;
    public AnimControl m_AnimControl;

    public Vector3 m_vLastApplyForce;
}

